#!/usr/bin/env python3
"""
Custom HTTP server that serves static files (like http.server) and
prints POST request details (headers, raw body, parsed parameters).
Responds to POST with an HTML page that has a button to return to the form.
"""

import http.server
import socketserver
import urllib.parse
import json
from pprint import pformat

PORT = 8000

class CustomHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
    """Handle GET (serve files) and POST (print & respond with back button)."""

    def do_POST(self):
        """Read POST data, parse it, print everything, then respond with a simple page."""
        content_length = int(self.headers.get('Content-Length', 0))
        raw_body = self.rfile.read(content_length)

        # Try to decode as UTF-8; fallback to repr if binary.
        try:
            raw_body_str = raw_body.decode('utf-8')
        except UnicodeDecodeError:
            raw_body_str = repr(raw_body)

        print(f"\n--- Received POST request to {self.path} ---")
        print("Headers:")
        for header, value in self.headers.items():
            print(f"  {header}: {value}")

        print(f"\nRaw body:\n{raw_body_str}")

        # Parse parameters if content-type is form-urlencoded
        parsed_params = {}
        content_type = self.headers.get('Content-Type', '')
        if 'application/x-www-form-urlencoded' in content_type:
            parsed_params = urllib.parse.parse_qs(raw_body_str)
            # parse_qs returns dict with list values (e.g., {'name': ['value']})
            # Flatten single-item lists for cleaner display.
            flat_params = {k: v[0] if len(v) == 1 else v for k, v in parsed_params.items()}
            parsed_params = flat_params
        else:
            # For other content types, just store a note.
            parsed_params = {"info": "Non-form data received (see raw body)"}

        print("\nParsed parameters (as Python dict):")
        print(pformat(parsed_params, indent=2))
        print("-" * 50)

        # Send response: a simple HTML page with a button to go back to the form.
        self.send_response(200)
        self.send_header('Content-Type', 'text/html; charset=utf-8')
        self.end_headers()

        # Build a nice summary for the response page (optional, for user feedback)
        param_summary = "<ul>"
        for key, value in parsed_params.items():
            param_summary += f"<li><strong>{key}</strong>: {value}</li>"
        if not parsed_params:
            param_summary = "<p>No parameters sent.</p>"
        else:
            param_summary += "</ul>"

        response_html = f"""<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>POST Received</title>
<style>
  body {{ font-family: sans-serif; max-width: 600px; margin: 2rem auto; text-align: center; }}
  button {{ background: #007bff; color: white; border: none; padding: 0.7rem 1.5rem; font-size: 1rem; border-radius: 4px; cursor: pointer; }}
  button:hover {{ background: #0056b3; }}
  .summary {{ background: #f0f0f0; padding: 1rem; border-radius: 8px; text-align: left; margin: 1rem 0; }}
</style>
</head>
<body>
<h2>✅ POST request received successfully</h2>
<p>Your data has been printed on the server console.</p>
<div class="summary">
  <h3>Parameters you sent:</h3>
  {param_summary}
</div>
<form action="/form.html" method="GET">
  <button type="submit">🔙 Go back to the form</button>
</form>
</body>
</html>"""
        self.wfile.write(response_html.encode('utf-8'))

    # GET is handled automatically by SimpleHTTPRequestHandler
    # (serves static files like form.html)

if __name__ == '__main__':
    with socketserver.TCPServer(("", PORT), CustomHTTPRequestHandler) as httpd:
        print(f"Serving HTTP on 0.0.0.0 port {PORT} (http://localhost:{PORT}/)")
        print("Press Ctrl+C to stop.\n")
        try:
            httpd.serve_forever()
        except KeyboardInterrupt:
            print("\nServer stopped.")